package org.loong.crypto.service.core.provider.impl;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import org.loong.crypto.core.algorithm.KeyAlgorithm;
import org.loong.crypto.service.core.context.CryptoContext;
import org.loong.crypto.service.core.provider.KeyGeneratorProvider;

/**
 * The base abstract class for key generator.
 * 
 * <p>
 * Supports the following algorithms:
 *
 * <ul>
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#AES}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#BLOWFISH}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#DES}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#DESEDE}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#HMAC_MD5}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#HMAC_SHA1}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#HMAC_SHA224}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#HMAC_SHA256}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#HMAC_SHA384}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#HMAC_SHA512}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#RC2}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#RC4}
 * <li>{@link org.loong.crypto.core.algorithm.KeyAlgorithm#SM4}
 * </ul>
 */
public abstract class BaseKeyGeneratorProvider implements KeyGeneratorProvider {

    /**
     * The supported key generator algorithms by the KeyGenerator provider class.
     */
    public static final Set<KeyAlgorithm> SUPPORTED_ALGORITHMS;

    /**
     * The cryptoContext.
     */
    private CryptoContext cryptoContext;
    
    static {
        Set<KeyAlgorithm> algs = new LinkedHashSet<>();
        algs.add(KeyAlgorithm.AES);
        algs.add(KeyAlgorithm.BLOWFISH);
        algs.add(KeyAlgorithm.DES);
        algs.add(KeyAlgorithm.DESEDE);
        algs.add(KeyAlgorithm.HMAC_MD5);
        algs.add(KeyAlgorithm.HMAC_SHA1);
        algs.add(KeyAlgorithm.HMAC_SHA224);
        algs.add(KeyAlgorithm.HMAC_SHA256);
        algs.add(KeyAlgorithm.HMAC_SHA384);
        algs.add(KeyAlgorithm.HMAC_SHA512);
        algs.add(KeyAlgorithm.RC2);
        algs.add(KeyAlgorithm.RC4);
        algs.add(KeyAlgorithm.SM4);
        SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(algs);
    }

    @Override
    public Set<KeyAlgorithm> supportedKeyAlgorithms() {
        return SUPPORTED_ALGORITHMS;
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public <T extends CryptoContext> T getCryptoContext() {
        return (T) cryptoContext;
    }

    @Override
    public void setCryptoContext(CryptoContext cryptoContext) {
        this.cryptoContext = cryptoContext;
    }
}
